package com.msx.risk.producer;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.msx.constants.StatusCode;
import com.msx.credit.service.CreditService;
import com.msx.pojo.*;
import com.msx.risk.refactoring.AuditFactory;
import com.msx.risk.service.RiskService;
import com.msx.risk.service.impl.RiskServiceImpl;
import com.msx.user.service.*;
import com.msx.util.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

/**
 * @author dutao
 * @create: 2020-06-16 10:19
 */
@Service(timeout = 6000,retries=0,version = "2.0.0")
@Slf4j
public class RiskProducerImpl implements RiskService {

    @Reference(version = "2.0.0")
    private UserProducerInterface userService;

    @Reference(version = "2.0.0")
    private CreditService creditService;

    @Reference(version = "2.0.0")
    private LinkManServiceInterface linkManServiceInterface;

    @Reference(version = "2.0.0")
    private OperatorServiceInterface operatorServiceInterface;

    @Reference(version = "2.0.0")
    private IdentityTaoBaoServiceInterface taoBaoServiceInterface;

    @Autowired
    private AuditFactory auditFactory;

    @Autowired
    private RiskServiceImpl riskService;

    public ResponseResult add(){
        try {
            addRiskControlRecord("第二联系人认证","0",1);
            return new ResponseResult(StatusCode.OK,"ok");
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseResult(StatusCode.ERROR,"Error");
        }

    }



    /**
     * @Author 豪少
     * @Description //TODO
     * @Date 11:05 2020/6/24
     * @Param  * @param orderId
     * @return java.lang.String
     * 根据订单号查询审核状态
     **/
    @Override
    public ResponseResult findAuditOrderStateByOrderId(String orderId){
        return this.riskService.findAuditOrderStateByOrderId(orderId);
    }



    /**
     * @Author 豪少
     * @Description //TODO
     * @Date 11:03 2020/6/24
     * @Param  * @param
     * @return com.msx.util.ResponseResult
     * 审核订单 定时器执行5秒一次
     **/
    @Scheduled(fixedRate = 5000)
    public ResponseResult responseCode() {
        //查询审核中记录
        List<AuditOrder> auditOrderByState = this.riskService.findAuditOrderByState("2");
        if(auditOrderByState.isEmpty() && auditOrderByState == null){
            log.info("没有审核中的订单!");
            return new ResponseResult(StatusCode.OK, "没有审核中的订单!");
        }
        //循环遍历
        for (AuditOrder auditOrder:auditOrderByState) {
            //身份认证审核结果
            boolean auditUser = auditUser(auditOrder);
            log.info("身份认证审核结果:" + auditUser);
            //黑白名单认证结果
            boolean auditBlackOrWhite = auditBlackOrWhite(auditOrder.getUserId(),auditOrder.getId());
            log.info("黑白名单审核结果:" + auditBlackOrWhite);
            //数据分析结果
            boolean analyzeData = analyzeData(auditOrder.getUserId(),auditOrder.getId());
            log.info("淘宝运营商数据分析结果:" + analyzeData);
            //生成随机数
            int num = (int) (Math.random() * 50 + 50);
            //三个有一个没通过
            if (!auditUser || !auditBlackOrWhite || !analyzeData) {
                //修改审核表的状态为审核未通过
                updateAuditOrder(auditOrder.getId(),"1",0,auditOrder.getOrderId(),auditOrder.getUserId(),new Date(),"0");
                return new ResponseResult(StatusCode.ERROR,"审核未通过!");
            }
            //随机数小于等于60把分数存在审核表并审核未通过
            if(num <= 60){
                updateAuditOrder(auditOrder.getId(),"1",num,auditOrder.getOrderId(),auditOrder.getUserId(),new Date(),"0");
                return new ResponseResult(StatusCode.ERROR,"审核未通过!");
            }
            updateAuditOrder(auditOrder.getId(),"0",num,auditOrder.getOrderId(),auditOrder.getUserId(),new Date(),"0");
            return new ResponseResult(StatusCode.OK,"审核通过！");
        }
        return new ResponseResult(StatusCode.ERROR, "审核失败!");
    }
    /**
     * @Author 豪少
     * @Description //TODO
     * @Date 9:58 2020/6/24
     * @Param  * @param auditOrder
     * @return boolean
     * 审核用户授权
     **/
    private boolean auditUser(AuditOrder auditOrder) {
        //根据审核中订单的用户id查询用户对象
         User user = this.userService.findById(auditOrder.getUserId());
        log.info("userz值"+user);
        if(StringUtils.isEmpty(user)){
            return false;
        }
        //启动工厂
        boolean result = auditFactory.getAudit(user, auditOrder.getId());

        return result;

    }
    /**
     * @param userId
     * @return boolean
     * 黑白名单联系人判断
     * @Author 豪少
     * @Description //TODO
     * @Date 10:37 2020/6/19
     * @Param * @param name
     **/
    private boolean auditBlackOrWhite(Integer userId, Integer auditOrderId) {
        //根据用户id查询用户对象
        User user = this.userService.findById(userId);
        if(StringUtils.isEmpty(user)){
            return false;
        }
        //根据用户名查询白名单
        WhiteList whiteList = this.riskService.findWhiteByUserName(user.getUserName());
        //根据用户名查询黑名单
        BlackList blackList = this.riskService.findBlackByUserName(user.getUserName());
        //根据用户人id查询联系人表
        ResponseResult linkManByUserId = this.linkManServiceInterface.findLinkManByUserId(userId);
        Linkman man = (Linkman) this.linkManServiceInterface.findLinkManByUserId(userId).getData();
        if(StringUtils.isEmpty(man)){
            addRiskControlRecord("联系人认证","1",auditOrderId);
            return false;
        }
        //第一联系人
        BlackList blackByUserNameOne = this.riskService.findBlackByUserName(man.getFirstName());
        //第二联系人
        BlackList blackByUserNameTwo = this.riskService.findBlackByUserName(man.getSecondName());
        //根据用户id查询审核表id
        AuditOrder auditOrderByUserId = this.riskService.findAuditOrderByUserId(userId);

        //启动工厂
        boolean result = auditFactory.getAuditBlackOrWhite(whiteList, blackList, man, blackByUserNameOne, blackByUserNameTwo, auditOrderByUserId.getId());
        return result;

    }

    /**
     * @return boolean
     * 分析数据
     * @Author 豪少
     * @Description //TODO
     * @Date 14:14 2020/6/19
     * @Param * @param userId
     **/
    private boolean analyzeData(Integer userId,Integer auditOrderId) {
        //根据用户id查询运营商数据
        Operator operator = (Operator) this.operatorServiceInterface.findOperatorByUserId(userId).getData();
        //根据用户id查询淘宝数据
        Taobao taobao = (Taobao) this.taoBaoServiceInterface.findTaobaoByUserId(userId).getData();
        //如果运营商和淘宝数据没有
        if(StringUtils.isEmpty(operator) || StringUtils.isEmpty(taobao)){
            //数据分析
            addRiskControlRecord("淘宝运营商数据分析","1",auditOrderId);
            return false;
        }
        //通过用户表id查询审核表的主键
        AuditOrder auditOrderByUserId = this.riskService.findAuditOrderByUserId(userId);
        //启动工厂
        boolean result =  auditFactory.getAnalyzeData(operator, taobao, auditOrderByUserId.getId());
        return result;
    }

    /**
     * @param score
     * @param orderId
     * @param userId
     * @param auditTime
     * @param isDelete
     * @return void
     * 添加审核记录
     * @Author 豪少
     * @Description //TODO
     * @Date 18:34 2020/6/22
     * @Param * @param state
     **/
    private void addAuditOrder(String state, Integer score, String orderId, Integer userId, Date auditTime, String isDelete) {
        AuditOrder auditOrder = new AuditOrder();
        auditOrder.setState(state);
        auditOrder.setScore(score);
        auditOrder.setOrderId(orderId);
        auditOrder.setUserId(userId);
        auditOrder.setAuditTime(auditTime);
        auditOrder.setIsDelete(isDelete);
        this.riskService.addAuditOrder(auditOrder);
    }

    /**
     * @Author 豪少
     * @Description //TODO
     * @Date 10:28 2020/6/23
     * @Param  * @param id
     * @param state
     * @param score
     * @param orderId
     * @param userId
     * @param auditTime
     * @param isDelete
     * @return void
     * 修改审核记录
     **/
    private void updateAuditOrder(Integer id, String state, Integer score, String orderId, Integer userId, Date auditTime, String isDelete) {
        AuditOrder auditOrder = new AuditOrder();
        auditOrder.setId(id);
        auditOrder.setState(state);
        auditOrder.setScore(score);
        auditOrder.setOrderId(orderId);
        auditOrder.setUserId(userId);
        auditOrder.setAuditTime(auditTime);
        auditOrder.setIsDelete(isDelete);
        this.riskService.updateAuditOrder(auditOrder);
    }

    /**
     * @Author 豪少
     * @Description //TODO
     * @Date 16:37 2020/6/27
     * @Param  * @param auditType
     * @param state
     * @param auditOrderId
     * @return void
     * 风控记录添加
     **/
    private void addRiskControlRecord(String auditType,String state,Integer auditOrderId){
        AuditcarefuleOrder auditcarefuleOrder = new AuditcarefuleOrder();
        auditcarefuleOrder.setAuditType(auditType);
        auditcarefuleOrder.setState(state);
        auditcarefuleOrder.setAuditOrderId(auditOrderId);
        auditcarefuleOrder.setAuditTime(new Date());
        auditcarefuleOrder.setIsDelete("0");
        riskService.addRiskOrder(auditcarefuleOrder);
    }

}
